/*
 * ﻿Copyright (C) 2012 NewMain Softech
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */
package com.newmainsoftech.ant.types;

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

import org.apache.tools.ant.ProjectComponent;
import org.apache.tools.ant.types.LogLevel;
import org.apache.tools.ant.types.Environment.Variable;

import com.newmainsoftech.ant.script.ReadMultiLineArgs;
import com.newmainsoftech.ant.taskdefs.JUnitTaskExt;

/**
 * Support class for {@link JUnitTaskExt} to implement multi-line arguments for system property.
 * 
 * @author <a href="mailto:artymt@gmail.com">Arata Y.</a>
 * @see JUnitTaskExt
 */
public class SysPropExt extends ProjectComponent {
	private String regExp = null;
		/**
		 * Set regular express string being used to extract each actual argument 
		 * from multiple-line arguments.
		 * @param regExp regular express string being used to extract each actual argument
		 */
		public void setRegExp( String regExp) {
			this.regExp = regExp;
		}
		/**
		 * Get regular express string being used to extract each actual argument 
		 * from multiple-line arguments.
		 * @return regular express string being used to extract each actual argument
		 */
		public String getRegExp() {
			return regExp;
		}
	
	private List<Variable> envVarList;
		public synchronized List<Variable> getEnvVarList() {
			if ( envVarList == null) {
				return new ArrayList<Variable>();
			}
			ArrayList<Variable> envVarListCopy = new ArrayList<Variable>( envVarList);
			return envVarListCopy;
		}
		public synchronized void setEnvVarList( List<Variable> envVarList) {
			if ( envVarList == null) {
				this.envVarList = new ArrayList<Variable>();
			}
			else {
				this.envVarList = new ArrayList<Variable>( envVarList);
			}
		}
	/**
	 * Add properties out of <code>text</code> input. 
	 * 
	 * @param text may consist of multiple pairs of property name and value. 
	 * Each pair of property name and value must consist of the format of property_name=property_value;  
	 * there must be no white space surrounding '=' delimiter between name and value of property. 
	 */
	public synchronized void addText( final String text) {
		if ( text == null) return;
		if ( text.trim().length() < 1) return;
		
		ReadMultiLineArgs readMultiLineArgs = new ReadMultiLineArgs();
			String regExp = getRegExp();
				if ( regExp != null) {
					readMultiLineArgs.setRegExpStr( regExp);
				}
		List<Variable> variableList = getEnvVarList();	
			List<String> propertyList = readMultiLineArgs.splitByPrefix( text, getProject());
			if ( propertyList.size() > 0) {
				ListIterator<String> listIterator = propertyList.listIterator();
				while( listIterator.hasNext()) {
					String propertyStr = listIterator.next();
						if ( !propertyStr.matches( "^\\s*[^\\s\\\"]+\\s*=\\s*[^\\s]+.*$")) {
							int lastVariableIndex = variableList.size() - 1;
							if ( lastVariableIndex < 0) {
								log( 
										String.format(
												"\"%1$s\" out of \"%2$s\" is going to be ignored " 
												+ "because it does not follow the format of " 
												+ "property_name=property_value.",
												propertyStr, text
												), 
										LogLevel.INFO.getLevel());
								listIterator.remove();
								continue; // while
							}
							// Append residue to previous property 
							Variable lastVariable = variableList.get( lastVariableIndex);
							lastVariable.setValue( 
									lastVariable.getValue().concat( " " + propertyStr));
							continue; // while
						}
					
					Variable envVar = new Variable();
						int delimiterIndex = propertyStr.indexOf( "=");
						String propertyName = propertyStr.substring( 0, delimiterIndex);
						envVar.setKey( propertyName);
						String propertyValue = propertyStr.substring( delimiterIndex + 1);
						envVar.setValue( propertyValue);
					variableList.add( envVar);
				}
			}
		setEnvVarList( variableList);
	}
}